#pragma once
#include "Common.hpp"
#include "Socket.hpp"
#include "InetAddr.hpp"
#include "protocol.hpp"
#include <functional>
using namespace sock_ns;

using process_t = std::function<std::shared_ptr<Respence>(std::shared_ptr<Request>)>;

class Service
{
public:
    Service(process_t process) : _process(process)
    {
    }
    ~Service()
    {
    }
    void IOExcute(SockpPtr sock, InetAddr &addr) // 执行IO交互
    {
        std::string packagestream;
        while (true)
        {
            ssize_t n = sock->Recv(&packagestream);
            if (n <= 0)
            {
                LOG(INFO, "client[%s] quit or recv error!\n", addr.GetAddrStr().c_str());
                break;
            }
            // 确定报文是否完整？
            std::string package = Decode(packagestream);
            if (package.empty())
                continue; // 如果不是完整的报文就重新读取

            auto res = Factor::BuildRequestDefault();
            // 对client发过来的请求进行反序列化
            res->Deserialization(package);
            // 业务处理
            auto resp = _process(res); // 发出请求，接收一个回应
            std::string res_package;

            // 对返回的应答进行序列化
            resp->Serialization(&res_package);

            // 形成完整报文
            std::string resjson = Encode(res_package);
            sock->Send(resjson);
        }
    }

private:
    process_t _process;
};
